package com.newtouch.xcd.admin.mfp.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.dubbo.config.annotation.Reference;
import com.google.common.collect.Lists;

import com.newtouch.xcd.cms.service.CrmService;
import com.newtouch.xcd.cms.to.crm.CrmFinancialProductData;
import com.newtouch.xcd.cms.to.crm.CrmFinancialProductIncomeDetailsItem;
import com.newtouch.xcd.cms.to.crm.CrmFinancialProductItem;
import com.newtouch.xcd.cms.to.crm.CrmTradeRecordItem;
import com.newtouch.xcd.common.constants.BaseDict;
import com.newtouch.xcd.common.constants.CrmDict;
import com.newtouch.xcd.common.constants.ResponseCode;
import com.newtouch.xcd.common.to.CommonResult;
import com.newtouch.xcd.common.utils.DateUtils;
import com.newtouch.xcd.common.utils.NumberUtils;
import com.newtouch.xcd.common.utils.StrUtils;
import com.newtouch.xcd.mfp.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@CrossOrigin
@RestController
@Api(tags = "MfpController", description = "2.3我的理财产品mfp(myFinancialProducts)")
@RequestMapping("/mfp")
public class MfpController {

    @Reference
    private CrmService crmService;

    /**
     * 2.3.01我的理财-主界面
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.3.01我的理财-主界面")
    @PostMapping(value = "/queryMyFinancialProductsMainPage")
    public CommonResult<MfpMyFinancialProductsMainPageRsp> queryMyFinancialProductsMainPage(HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        //理财产品
        CrmFinancialProductData crmFinancialProductData = this.crmService.queryFinancialProductByCustomerId(customId);

        //判断这个人有没有理财产品
        if (crmFinancialProductData == null) {
            return CommonResult.error(ResponseCode.R403.getCode(), ResponseCode.R403.getMessage());
        }

        //理财产品列表
        List<CrmFinancialProductItem> crmFinancialProductItemList = crmFinancialProductData.getFinancialProductList();

        if (CollUtil.isEmpty(crmFinancialProductItemList)) {
            return CommonResult.error(ResponseCode.R403.getCode(), ResponseCode.R403.getMessage());
        }

        MfpMyFinancialProductsMainPageRsp rsp = new MfpMyFinancialProductsMainPageRsp();

        //理财产品对象
        List<FinancialProductItem> financialProductItemList = new ArrayList<>();

        for (CrmFinancialProductItem crmFinancialProductItem : crmFinancialProductItemList) {

            FinancialProductItem financialProductItem = new FinancialProductItem();

            financialProductItem.setFinancialProductName(StrUtils.calFinProductName(crmFinancialProductItem.getProductName()));
            financialProductItem.setExpectedYield(NumberUtils.money(crmFinancialProductItem.getExpectedYield(), "#.#"));
            financialProductItem.setTotalAmount(NumberUtils.money(crmFinancialProductItem.getTotalAmount()));
            financialProductItem.setProductType(crmFinancialProductItem.getProductType());
            financialProductItem.setFinancialProductContractNum(crmFinancialProductItem.getProductNum());
            financialProductItem.setArrivalFlag(crmFinancialProductItem.getExpireFlag());
            financialProductItem.setProductPeriod(crmFinancialProductItem.getProductPeriod());
            String startDate = DateUtils.format(crmFinancialProductItem.getStartDate(), "yyyy-MM-dd", "yyyy/MM/dd");

            String productRange = "";
            String endDate = crmFinancialProductItem.getEndDate();
            if (StrUtils.isNotBlank(endDate)) {
                endDate = DateUtils.format(endDate, "yyyy-MM-dd", "yyyy/MM/dd");
                productRange = startDate + "-" + endDate;
            } else {
                productRange = startDate;
            }

            financialProductItem.setStartAndEndDates(productRange);

            //理财产品收益明细列表
            List<CrmFinancialProductIncomeDetailsItem> crmFinancialProductIncomeDetailsItemList = crmFinancialProductItem.getIncomeDetailsList();

            //理财产品收益明细
            List<FinancialProductIncomeDetailsItem> financialProductIncomeDetailsItemList = new ArrayList<>();

            if (CollUtil.isNotEmpty(crmFinancialProductIncomeDetailsItemList)) {
                for (CrmFinancialProductIncomeDetailsItem crmFinancialProductIncomeDetailsItem : crmFinancialProductIncomeDetailsItemList) {
                    FinancialProductIncomeDetailsItem financialProductIncomeDetailsItem = new FinancialProductIncomeDetailsItem();
                    financialProductIncomeDetailsItem.setIncomeDate(DateUtils.format(crmFinancialProductIncomeDetailsItem.getIncomeDate(), "yyyy-MM-dd", "yyyyMMdd"));
                    financialProductIncomeDetailsItem.setIncomeAmount(NumberUtils.formatMoney(crmFinancialProductIncomeDetailsItem.getIncomeAmount()));

                    financialProductIncomeDetailsItemList.add(financialProductIncomeDetailsItem);
                }

                financialProductIncomeDetailsItemList.sort(Comparator.comparing(FinancialProductIncomeDetailsItem::getIncomeDate).reversed());
            }

            financialProductItem.setIncomeDetailsList(financialProductIncomeDetailsItemList);

            financialProductItemList.add(financialProductItem);
        }

        financialProductItemList.sort(Comparator.comparing(FinancialProductItem::getArrivalFlag));

        //第一个展开
        if (CollUtil.isNotEmpty(financialProductItemList)) {
            if(CollUtil.isNotEmpty(financialProductItemList.get(0).getIncomeDetailsList())){
                financialProductItemList.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());
            }
        }

        rsp.setFinancialProductList(financialProductItemList);
        rsp.setProductAmountHeld(NumberUtils.money(crmFinancialProductData.getProductAmountHeld()));
        rsp.setCumulativeProductAmount(NumberUtils.money(crmFinancialProductData.getCumulativeProductAmount()));
        rsp.setHoldingProductIncome(NumberUtils.money(crmFinancialProductData.getHoldingProductIncome()));
        rsp.setTotalProductIcome(NumberUtils.money(crmFinancialProductData.getTotalProductIcome()));

        return CommonResult.success(rsp);
    }

    /**
     * 2.3.02我的理财-基金交易明细
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.3.02我的理财-基金交易明细")
    @PostMapping(value = "/queryFundTradingDetails")
    public CommonResult<MfpFundTradingDetailsRsp> queryFundTradingDetails(@Valid @RequestBody MfpFundTradingDetailsReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        //理财产品
        CrmFinancialProductData crmFinancialProductData = this.crmService.queryFinancialProductByCustomerId(customId);

        //判断这个人有没有理财产品
        if (crmFinancialProductData == null) {
            return CommonResult.error(ResponseCode.R403.getCode(), ResponseCode.R403.getMessage());
        }

        //理财产品列表
        List<CrmFinancialProductItem> crmFinancialProductItemList = crmFinancialProductData.getFinancialProductList();

        if (CollUtil.isEmpty(crmFinancialProductItemList)) {
            return CommonResult.error(ResponseCode.R403.getCode(), ResponseCode.R403.getMessage());
        }

        //基金编号
        String productNum = req.getFinancialProductContractNum();

        //产品期号
        String productPeriod = req.getProductPeriod();

        //根据基金编号、产品期号 进行过滤
        crmFinancialProductItemList = crmFinancialProductItemList.stream().filter(o -> o.getProductNum().equals(productNum)
                && o.getProductPeriod().equals(productPeriod)).collect(Collectors.toList());

        //鉴权
        if (CollUtil.isEmpty(crmFinancialProductItemList)) {
            return CommonResult.error(ResponseCode.R406.getCode(), ResponseCode.R406.getMessage());
        }

        //理财产品（对象）
        CrmFinancialProductItem crmFinancialProductItem = crmFinancialProductItemList.get(0);

        //基金产品名字，去除期号
        String fundProductName = StrUtils.calFinProductName(crmFinancialProductItem.getProductName());

        //交易明细列表
        List<CrmTradeRecordItem> tradeRecordList = crmFinancialProductItem.getTradeRecordList();

        //先根据年月yyyy.MM进行分组
        Map<String, List<CrmTradeRecordItem>> yearMonthMap = tradeRecordList.stream().collect(
                Collectors.groupingBy(o -> DateUtils.format(o.getTradeDate(), "yyyy-MM-dd", "yyyy.MM")));

        //计算续存金额 = sum(买入)-sum(卖出)
        Double sumBuy = tradeRecordList.stream().filter(o -> CrmDict.BuyFlag.BUY.getCode().equals(o.getBuyFlag())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getTradeAmount()))).sum();
        Double sumSell = tradeRecordList.stream().filter(o -> CrmDict.BuyFlag.SELL.getCode().equals(o.getBuyFlag())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getTradeAmount()))).sum();
        Double existenceAmount = sumBuy - sumSell;

        //基金交易明细列表
        List<FundTradingDetailsItem> fundTradingDetailsList = new ArrayList<>();

        yearMonthMap.keySet().forEach(month -> {

            List<CrmTradeRecordItem> tradeMonthList = yearMonthMap.get(month);

            FundTradingDetailsItem fundTradingDetailsItem = new FundTradingDetailsItem();
            fundTradingDetailsItem.setFundTradingYear(month);

            Double totalBuyAmount = tradeMonthList.stream().filter(o -> CrmDict.BuyFlag.BUY.getCode().equals(o.getBuyFlag())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getTradeAmount()))).sum();
            Double totalSellAmount = tradeMonthList.stream().filter(o -> CrmDict.BuyFlag.SELL.getCode().equals(o.getBuyFlag())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getTradeAmount()))).sum();

            fundTradingDetailsItem.setTotalBuyAmount(NumberUtils.money(totalBuyAmount));
            fundTradingDetailsItem.setTotalSellAmount(NumberUtils.money(totalSellAmount));

            List<FundTradingDayDetailsItem> fundTradingDayDetailsList = new ArrayList<>();
            Map<String, List<CrmTradeRecordItem>> dayMap = tradeMonthList.stream().collect(Collectors.groupingBy(o -> o.getTradeDate()));
            dayMap.keySet().forEach(tradeDate -> {

                List<CrmTradeRecordItem> dayTradeList = dayMap.get(tradeDate);

                FundTradingDayDetailsItem fundTradingDayDetailsItem = new FundTradingDayDetailsItem();
                fundTradingDayDetailsItem.setFundTradingMonthDate(DateUtils.format(tradeDate, "yyyy-MM-dd", "MM/dd"));

                List<FundTradingActionItem> fundTradingActionList = new ArrayList<>();

                dayTradeList.forEach(dayTrade -> {
                    FundTradingActionItem fundTradingActionItem = new FundTradingActionItem();

                    String tradeType = dayTrade.getTradeType();

                    fundTradingActionItem.setFundTradingActionMark(tradeType.substring(0,1));
                    fundTradingActionItem.setFundTradingAction(tradeType);
                    fundTradingActionItem.setFundProductName(fundProductName);
                    fundTradingActionItem.setFundTradingAmount(NumberUtils.money(dayTrade.getTradeAmount()));
                    fundTradingActionItem.setFundTradingFlag(dayTrade.getBuyFlag());
                    fundTradingActionList.add(fundTradingActionItem);
                });

                //根据买卖标志排序
                fundTradingActionList.sort(Comparator.comparing(FundTradingActionItem::getFundTradingFlag).reversed());

                fundTradingDayDetailsItem.setFundTradingActionList(fundTradingActionList);

                fundTradingDayDetailsList.add(fundTradingDayDetailsItem);
            });

            //按日期降序
            fundTradingDayDetailsList.sort(Comparator.comparing(FundTradingDayDetailsItem::getFundTradingMonthDate).reversed());

            fundTradingDetailsItem.setFundTradingDayDetailsList(fundTradingDayDetailsList);
            fundTradingDetailsList.add(fundTradingDetailsItem);
        });

        fundTradingDetailsList.sort(Comparator.comparing(FundTradingDetailsItem::getFundTradingYear).reversed());

        //第一个标志展开
        fundTradingDetailsList.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());

        MfpFundTradingDetailsRsp rsp = new MfpFundTradingDetailsRsp();
        rsp.setExistenceAmount(NumberUtils.money(existenceAmount));
        rsp.setFundTradingDetailsList(fundTradingDetailsList);

        return CommonResult.success(rsp);
    }
}
